#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <memory.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include "devfb.h"


int DevFb_initialize(DevFb *dev, DevFbConfig *devConfig)
{
    int ret;

    /* initialize */
    dev->bufferNumber = 1;
    /* open */
    dev->node = devConfig->node;
    dev->handle = open(dev->node, O_RDWR);
    if (dev->handle < 0) {
        perror("DevFb_initialize: open error");
        return -1;
    }
    /* get info */
    ret = ioctl(dev->handle, FBIOGET_FSCREENINFO, &dev->fbfixinfo);
    if (ret < 0) {
        perror("DevFb_initialize: FBIOGET_FSCREENINFO error");
        return -1;
    }
    ret = ioctl(dev->handle, FBIOGET_VSCREENINFO, &dev->fbvarinfo);
    if (ret < 0) {
        perror("DevFb_initialize: FBIOGET_VSCREENINFO error");
        return -1;
    }
    /* mmap */
    dev->buffer = calloc(dev->bufferNumber, sizeof(Buffer));
    if (NULL == dev->buffer) {
        printf("DevFb_initialize: calloc devHdmiBuffer failed\n");
        return -1;
    }
    dev->buffer[0].index = 0;
    dev->buffer[0].length = dev->fbvarinfo.yres*dev->fbfixinfo.line_length;
    dev->buffer[0].start = (char *)mmap (
                0, dev->buffer[0].length,
                (PROT_READ|PROT_WRITE), MAP_SHARED, dev->handle, 0);
    if (dev->buffer[0].start == MAP_FAILED) {
        printf("DevFb_initialize:  mmap error\n");
        return -1;
    }
    dev->buffer[0].paddr = dev->fbfixinfo.smem_start;
    return 0;
}

int DevFb_uninitialize(DevFb *dev)
{
    close(dev->handle);
    return 0;
}

inline int DevFb_unblank(DevFb *dev)
{
    int blank = FB_BLANK_UNBLANK;
    if (ioctl(dev->handle, FBIOBLANK, blank) < 0) {
        printf("DevFb_unblank: FB_BLANK_UNBLANK error");
        return -1;
    }
    return 0;
}
